package br.com.lh.urabuilder.helper {
	import br.com.lh.urabuilder.business.ArrowManager;
	import br.com.lh.urabuilder.business.ViewManager;
	import br.com.lh.urabuilder.domain.view.UraElement;
	import br.com.lh.urabuilder.domain.xml.UraActionWithNext;
	import br.com.lh.urabuilder.event.AddActionEvent;
	import br.com.lh.urabuilder.event.LinkActionEvent;
	import br.com.lh.urabuilder.helper.dragdrop.IDragAndDropDelegator;
	import br.com.lh.urabuilder.model.UraModelLocator;
	import br.com.lh.urabuilder.view.ActionComponent;
	import br.com.lh.urabuilder.view.arrow.ArrowContainer;
	
	import com.adobe.cairngorm.control.CairngormEventDispatcher;
	
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import mx.containers.Canvas;
	import mx.controls.Image;
	import mx.core.DragSource;
	import mx.core.UIComponent;
	import mx.events.DragEvent;

	public class DragAndDropHelper
	{
		private var parentComponent:Canvas;
		private var componentManager:ViewManager;
		private var scrollHelper:ScrollHelper;
		private var mouseEventHelper:MouseEventHelper;
		private var dragDropDelegator:IDragAndDropDelegator
		public function DragAndDropHelper(parent:UIComponent,
			componentManager:ViewManager,
			scrollHelper:ScrollHelper,
			mouseEventHelper:MouseEventHelper,
			dragDropDelegator:IDragAndDropDelegator)
		{
			this.parentComponent=parent as Canvas;
			this.componentManager=componentManager;
			this.scrollHelper=scrollHelper;
			this.mouseEventHelper=mouseEventHelper;
			this.dragDropDelegator=dragDropDelegator;
		}
		public function initDrag(event:MouseEvent, type:String, created:Boolean):void
		{
			if (!mouseEventHelper.isMouseMovingComponent && created) {
				return ;
			}
			var dragInitiator:UIComponent=UIComponent(event.currentTarget);
			var ds:DragSource=new DragSource();
			ds.addData(event.localX, 'localx');
			ds.addData(event.localY, 'localy');
			ds.addData(type, 'type');
			ds.addData(created, 'created');
			var dragProxy:UIComponent;
			if (created) {
				var textLabel:String=ActionComponent(dragInitiator).textLabel;
				ds.addData(textLabel, 'text');
				dragProxy=new ActionComponent();
				ActionComponent(dragProxy).loadComponent(type, event.localX, event.localY, componentManager.getComponents().length);
				ActionComponent(dragProxy).textLabel=textLabel;
			} else {
				dragProxy=new Image();
				Image(dragProxy).source=Image(dragInitiator).source;
				dragProxy.height=dragInitiator.height;
				dragProxy.width=dragInitiator.width;
			}
			dragDropDelegator.startDragging(dragInitiator, ds, event, dragProxy);
		}
		public function doAccept(event:DragEvent):void
		{
			if (!mouseEventHelper.isComponentMovingAllowed()) {
				mouseEventHelper.isMouseMovingArrow=false;
				return ;
			}
			var type:String=event.dragSource.dataForFormat('type').toString();
			var created:Boolean=event.dragSource.dataForFormat('created');
			var finalYPosition:Number=event.localY + parentComponent.verticalScrollPosition;
			var finalXPosition:Number=event.localX + parentComponent.horizontalScrollPosition;
			if (type == "arrow") {
				acceptArrow(finalXPosition, finalYPosition, created, event);
			} else {
				acceptComponent(finalXPosition, finalYPosition, type, created, event);
			}
			mouseEventHelper.isMouseMovingComponent=false;
			scrollHelper.terminateScroll(finalXPosition, finalYPosition);
		}
		private function acceptArrow(finalXPosition:Number, finalYPosition:Number, created:Boolean, event:DragEvent):void
		{
			if (created) {
				positionComponentOnScreen(event.dragInitiator as UIComponent, event, finalXPosition, finalYPosition);
			} else {
				var arrowManager:ArrowManager=UraModelLocator.getInstance().arrowManager;
				var startPoint:Point=new Point(finalXPosition - 50, finalYPosition);
				var endPoint:Point=new Point(finalXPosition + 50, finalYPosition);
				var arrowContainer:ArrowContainer =arrowManager.insertArrow(startPoint, endPoint);
				arrowContainer.addEventListener(MouseEvent.MOUSE_MOVE, function(e:MouseEvent):void {
						initDrag(event, "arrow", true);});
			}
		}
		private function acceptComponent(finalXPosition:Number, finalYPosition:Number, type:String, created:Boolean, event:DragEvent):void
		{
			var component:ActionComponent;
			if (created == true) {
				if (event.ctrlKey) {
					component=new ActionComponent();
					component.loadComponent(type, finalXPosition, finalYPosition, componentManager.getComponents().length);
					createNewComponent(type, component, finalXPosition, finalYPosition);
				} else {
					component=event.dragInitiator as ActionComponent;
					positionComponentOnScreen(component, event, finalXPosition, finalYPosition);
				}
			} else {
				component=new ActionComponent();
				component.loadComponent(type, finalXPosition, finalYPosition, componentManager.getComponents().length);
				createNewComponent(type, component, finalXPosition, finalYPosition);
			}
		}
		public function createNewComponent(type:String, component:ActionComponent, finalXPosition:Number, finalYPosition:Number):void
		{
			dragDropDelegator.endDragging(parentComponent);
			addListeners(component, type);
			var addActionEvent:AddActionEvent=new AddActionEvent(component);
			CairngormEventDispatcher.getInstance().dispatchEvent(addActionEvent);
		}
		private function positionComponentOnScreen(component:UIComponent, event:DragEvent, xPos:Number, yPos:Number):void
		{
			var initx:int=event.dragSource.dataForFormat('localx')as int;
			var inity:int=event.dragSource.dataForFormat('localy')as int;
			component.x=xPos - initx;
			component.y=yPos - inity;
			dragDropDelegator.endDragging(parentComponent);
		}
		public function addListeners(uraComponent:ActionComponent, type:String):void
		{
			uraComponent.doubleClickEnabled=true;
			uraComponent.addEventListener(MouseEvent.MOUSE_MOVE, function(e:MouseEvent):void {
					initDrag(e, type, true);});
		}
		public function mouseDown(event:MouseEvent):void
		{
			if (mouseEventHelper.isComponentMovingAllowed()) {
				mouseEventHelper.isMouseMovingComponent=true;
			}
		}
		public function selectObject(event:MouseEvent):void
		{
			mouseEventHelper.isMouseMovingComponent=false;
			var endComponent:ActionComponent=ActionComponent(Image(event.currentTarget).parent);
			if (event.ctrlKey) {
				for each(var element:UraElement in componentManager.getSelectedComponents()) {
					var uraActionComponent:ActionComponent=element as ActionComponent;
					if (uraActionComponent != null && !uraActionComponent.isLinked() && uraActionComponent.uraAction is UraActionWithNext) {
						CairngormEventDispatcher.getInstance().dispatchEvent(new LinkActionEvent(uraActionComponent, endComponent));
					}
				}
			} else {
				componentManager.selectComponent(endComponent, true, event.shiftKey);
			}
		}
	}
}